#pragma once
#include"Command.hpp"


class UdpServer
{
public:
    UdpServer( uint16_t port = gdefaultport) : 
    _port(port),
    _isrunning(false)
    {
    }

    void InitServer()
    {
        // 1. 创建socket
        _sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        if (_sockfd < 0)
        {
            perror("socket error");
            return;
        }

        // 2. 填充网络信息，并bind绑定
        struct sockaddr_in serv_addr;
        serv_addr.sin_family = AF_INET; // 保持一致性
        serv_addr.sin_port = ::htons(_port);
        serv_addr.sin_addr.s_addr= ::htonl(INADDR_ANY);

        // 加载进入内核
        int n = bind(_sockfd,CONV(&serv_addr), sizeof(sockaddr_in));
        if (n == -1)
        {
            perror("bind error");
            return;
        }

        std::cout<<"bind success IP:"<<"port:"<<_port<<std::endl;
    }

    void Start()
    {
        if(_isrunning) 
            return ;

        _isrunning = true;
        std::cout<<"Begining receive"<<std::endl;
        // 服务器死循环接受数据
        while (true)
        {
            struct sockaddr_in client_addr;
            socklen_t addr_len = sizeof(client_addr);
            char buffer[1024];
            // 阻塞接受
            ssize_t n = recvfrom(_sockfd, buffer, sizeof(buffer) - 1, 0, CONV(&client_addr), &addr_len);
            if (n == -1)
            {
                perror("recvfrom error");
                continue;
            }

            buffer[n] = 0;
            std::string ip = ::inet_ntoa(client_addr.sin_addr);
            uint16_t port = ::ntohs(client_addr.sin_port);
            printf("from %s:%u:%s\n", ip.c_str(), port, buffer);

            // 回显
            std::string info = "echo #";
            info += buffer;
            ::sendto(_sockfd, info.c_str(), info.size(), 0, CONV(&client_addr), addr_len);
        }
    }
    ~UdpServer()
    {
        if (_isrunning)
            ::close(_sockfd);
    }

private:
    int _sockfd;
    uint16_t _port;  // 服务器未来的端口号
    bool _isrunning; // 服务器运行状态
};


// V1本地网络连接
// class UdpServer
// {
// public:
//     UdpServer(std::string ip = gdefaultip, uint16_t port = gdefaultport) : 
//     _port(port),
//     _ip(ip)
//     {

//     }

//     void InitServer()
//     {
//         // 1. 创建socket
//         _sockfd = socket(AF_INET, SOCK_DGRAM, 0);
//         if (_sockfd < 0)
//         {
//             std::cout << "窗口建立错误" << std::endl;
//             return;
//         }

//         // 2. 填充网络信息，并bind绑定
//         struct sockaddr_in serv_addr;
//         serv_addr.sin_family = AF_INET; // 保持一致性
//         serv_addr.sin_port = ::htons(_port);
//         serv_addr.sin_addr.s_addr = ::inet_addr(_ip.c_str());

//         // 加载进入内核
//         int n = bind(_sockfd,CONV(&serv_addr), sizeof(sockaddr_in));
//         if (n == -1)
//         {
//             std::cout << "绑定错误" << std::endl;
//             return;
//         }

//         std::cout<<"绑定成功 IP:"<<_ip<<"端口:"<<_port<<std::endl;
//     }

//     void Start()
//     {
//         if(_isrunning) 
//             return ;

//         _isrunning = true;
//         std::cout<<"开始接受数据"<<std::endl;
//         // 服务器死循环接受数据
//         while (true)
//         {
//             struct sockaddr_in client_addr;
//             socklen_t addr_len = sizeof(client_addr);
//             char buffer[1024];
//             // 阻塞接受
//             int n = recvfrom(_sockfd, buffer, sizeof(buffer) - 1, 0, CONV(&client_addr), &addr_len);
//             if (n == -1)
//             {
//                 std::cout << "读取UDP错误" << std::endl;
//                 continue;
//             }

//             buffer[n] = 0;
//             std::string ip = ::inet_ntoa(client_addr.sin_addr);
//             uint16_t port = ::ntohs(client_addr.sin_port);
//             printf("来自%s:%u:%s\n", ip.c_str(), port, buffer);

//             // 回显
//             std::string info = "echo #";
//             info += buffer;

//             ::sendto(_sockfd, info.c_str(), info.size(), 0, CONV(&client_addr), addr_len);
//         }
//     }
//     ~UdpServer()
//     {
//         if (_isrunning)
//             ::close(_sockfd);
//     }

// private:
//     int _sockfd;
//     uint16_t _port;  // 服务器未来的端口号
//     std::string _ip; // 服务器所对应的IP
//     bool _isrunning; // 服务器运行状态
// };